// @Author EthanScriptOn
// @Desc
package config_parser

import (
	"errors"
	"fmt"
	"gitee.com/fatzeng/srf_switch_basic_components/initialization"
	"gitee.com/fatzeng/srf_switch_basic_components/util"
	"gitee.com/fatzeng/srf_switch_config/config_context"
	"gitee.com/fatzeng/srf_switch_config/config_define"
	"math"
	"strings"
)

var duplicateLoadingRule = func() *initialization.OnceInitializer {
	initializer := initialization.GenerateOnceInitializer(config_define.ParserPositionTag, config_define.DuplicateLoadingRuleInitTag)
	err := initializer.Set(math.MaxInt, func() (result interface{}, err error) {
		duplicateLoading := make([]*DuplicateLoadingList, 0)
		duplicateLoading = append(duplicateLoading, &DuplicateLoadingList{
			NodeElemType: config_define.SRF_LOAD_FILE_PATH,
			CustomizedDuplicateLoadingFunc: func(ctx *config_context.ConfigInitializationContext, segmentVal interface{}) ([]string, error) {
				segmentValStr, ok := segmentVal.(string)
				if !ok {
					return nil, fmt.Errorf("segmentVal is not string segmentVal is %v", segmentVal)
				}
				return getRouteDuplicateLoadingPath(segmentValStr)
			},
		})
		duplicateLoading = append(duplicateLoading, &DuplicateLoadingList{
			NodeElemType: config_define.SRF_ENV,
			CustomizedDuplicateLoadingFunc: func(ctx *config_context.ConfigInitializationContext, segmentVal interface{}) ([]string, error) {
				segmentValStr, ok := segmentVal.(string)
				if !ok {
					return nil, fmt.Errorf("segmentVal is not string segmentVal is %v", segmentVal)
				}
				return getEnvironmentDuplicateLoadingPath(ctx, segmentValStr)
			},
		})
		return duplicateLoading, nil
	})
	if err != nil {
		panic(err)
	}
	return initializer
}()

func getRouteDuplicateLoadingPath(path string) ([]string, error) {
	isDir, err := util.IsDir(path)
	if err != nil {
		return nil, err
	}
	if isDir {
		filePaths, err := util.GetDirFiles(path, nil)
		if err != nil {
			return nil, err
		}
		return *filePaths, nil
	}
	return []string{path}, nil
}

func getEnvironmentDuplicateLoadingPath(ctx *config_context.ConfigInitializationContext, envVal string) ([]string, error) {
	filePath, err := ctx.GetFilePath()
	if err != nil {
		return nil, err
	}
	if filePath == "" {
		return nil, errors.New("filePath is empty, Unable to obtain the environment path")
	}
	directory := util.GetDirectory(filePath)
	filePaths, err := util.GetDirFiles(directory, nil)
	if err != nil {
		return nil, err
	}
	targetPaths := make([]string, 0)
	for _, path := range *filePaths {
		if strings.ContainsAny(path, envVal) {
			targetPaths = append(targetPaths, path)
		}
	}
	return targetPaths, nil
}
